package com.systemsjr.jrbbf;

import java.io.IOException;
import java.util.Enumeration;

import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.io.file.FileSystemRegistry;

import net.rim.device.api.database.Database;
import net.rim.device.api.database.DatabaseException;
import net.rim.device.api.database.DatabaseFactory;
import net.rim.device.api.database.DatabaseOptions;
import net.rim.device.api.database.DatabaseSecurityOptions;
import net.rim.device.api.database.Statement;
import net.rim.device.api.io.URI;
import net.rim.device.api.system.CodeModuleManager;
import net.rim.device.api.system.CodeSigningKey;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;

import com.systemsjr.jrbbf.expense.ExpenseTypeScreen;
import com.systemsjr.jrbbf.expense.ManageExpenseType;

/**
 * This class extends the UiApplication class, providing a
 * graphical user interface.
 */
public class ExpenseUI extends UiApplication
{
	private static final String DB_NAME = "ExpenseManager";
    /**
     * Entry point for application
     * @param args Command line arguments (not used)
     */ 
    public static void main(String[] args) throws Exception
    {
        // Create a new instance of the application and make the currently
        // running thread the application's event dispatch thread.
    	ExpenseUI theApp = new ExpenseUI();
        //errorDialog("2");
        theApp.enterEventDispatcher();
    }
    

    /**
     * Creates a new Expense object
     */
    public ExpenseUI() throws Exception
    {        
        // Push a screen onto the UI stack for rendering.
        //pushScreen(new ExpenseScreen());
    	// Determine if an SDCard is present 
        boolean sdCardPresent = false;
        String root = null;
        Enumeration e = FileSystemRegistry.listRoots();
        //errorDialog("3");
        while (e.hasMoreElements())
        {
            root = (String)e.nextElement();
            System.out.println(root);
            errorDialog(root);
            if(root.equalsIgnoreCase("sdcard/"))
            {
                sdCardPresent = true;
            }     
        }            
        if(!sdCardPresent)
        {
            UiApplication.getUiApplication().invokeLater(new Runnable()
            {
                public void run()
                {
                    Dialog.alert("This application requires an SD card to be present. Exiting application...");
                    System.exit(0);            
                } 
            });        
        }
        else
        {
        	boolean dbExists = false;
            String dbLocation = "/SDCard/databases/JRSystems/jrfinance/"; 
            System.out.println(dbLocation);
            
            //create URI
            URI uri;// = URI.create(dbLocation + DB_NAME);
            System.out.println(dbLocation + DB_NAME);
            Database db;
            
            try{
            	FileConnection fileConnection = (FileConnection)Connector.open("file:///SDCard/databases/JRSystems/jrfinance/ExpenseManager");
            	
            	if(!fileConnection.exists()){
            		dbExists = false;
            	} else{
            		dbExists = true;
            	}            	
            } catch(IOException ioe){
            	errorDialog("Problem opening file" + ioe.toString());
            }
            
            uri = URI.create("/SDCard/databases/JRSystems/jrfinance/ExpenseManager");
            // Open or create a plain text database.  This will create the
            // directory and file defined by the URI (if they do not already exist).
            db = DatabaseFactory.openOrCreate(uri);  
            System.out.println("db created");
            System.out.println("checking");
        	Statement st = null;
            db = DatabaseFactory.open("file://" + dbLocation + DB_NAME);
            System.out.println("DatabaseFactory opened");
            
            // Add tables if the files was just created
            if(!dbExists){
	            st = db.createStatement("CREATE TABLE ExpenseType (Code TEXT, ExpenseType TEXT)");
	            System.out.println("statement created");
	            st.prepare();
	            System.out.println("statement prepared");
	            st.execute();
	            System.out.println("expense type created");
	            st = db.createStatement("CREATE TABLE Expense (FkExpenseType TEXT, Amount TEXT)");
	            st.prepare();
	            st.execute();
	            System.out.println("expense created");
            }
            // Retrieve the code signing key for the XYZ key file
            CodeSigningKey codeSigningKey = CodeSigningKey.get(CodeModuleManager.getModuleHandle( "FinanceManager" ), "XYZ");
            
            try
            {
                // Encrypt and protect the database.  If the database is already
                // encrypted, the method will exit gracefully. 
                DatabaseFactory.encrypt(uri, new DatabaseSecurityOptions(codeSigningKey));
            }
            catch(DatabaseException dbe)
            {
                errorDialog("Encryption failed - " + dbe.toString());         
            }
            
            // Create a new DatabaseOptions object forcing foreign key constraints
            DatabaseOptions databaseOptions = new DatabaseOptions();
            databaseOptions.set( "foreign_key_constraints", "on" );
            System.out.println("constraints");
            // Open the database            
            db = DatabaseFactory.open(uri, databaseOptions);
            
            // Create a new main screen and push it onto the display stack
            ExpenseTypeScreen screen = new ExpenseTypeScreen(new ManageExpenseType(db));      
            pushScreen(screen);
            System.out.println("screen pushed");
        }
    } 
       
   /**
    * Presents a dialog to the user with a given message
    * @param message The text to display
    */
   public static void errorDialog(final String message)
   {
       UiApplication.getUiApplication().invokeLater(new Runnable()
       {
           public void run()
           {
               Dialog.alert(message);
           } 
       });
   }
}
